using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;

public class ProgressiveWaveManager : MonoBehaviour
{
    [Header("Wave Settings")]
    [SerializeField] private GameObject zombiePrefab;
    [SerializeField] private int initialZombieCount = 3;

    [Header("Spawn Settings")]
    [SerializeField] private Transform[] spawnPoints;
    [SerializeField] private float spawnRadius = 2f;
    [SerializeField] private float spawnInterval = 2f;

    [Header("Difficulty Progression")]
    [SerializeField] private float difficultyIncreaseRate = 0.1f;

    private bool isSpawning;
    private bool isWaveActive;
    private bool canStartNextWave;
    private int currentWave = 0;

    private int zombiesAlive;
    private int zombiesSpawned;
    private int zombiesInCurrentWave;
    private int totalZombiesKilled = 0;

    public static ProgressiveWaveManager Instance { get; private set; }

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }

    private void Start()
    {
        StartNextWave();
    }

    private void Update()
    {
        if (Keyboard.current != null &&
            Keyboard.current.enterKey.wasPressedThisFrame &&
            canStartNextWave &&
            !isWaveActive)
        {
            StartNextWave();
        }
    }

    #region Wave Management
    public void StartNextWave()
    {
        if (isWaveActive)
            return;

        currentWave++;
        zombiesInCurrentWave = Mathf.RoundToInt(initialZombieCount * (1 + (currentWave - 1) * difficultyIncreaseRate));
        zombiesAlive = 0;
        zombiesSpawned = 0;
        isWaveActive = true;
        canStartNextWave = false;

        StartCoroutine(SpawnWave());
    }

    private IEnumerator SpawnWave()
    {
        isSpawning = true;

        while (zombiesSpawned < zombiesInCurrentWave)
        {
            SpawnZombie();
            zombiesSpawned++;
            zombiesAlive++;

            yield return new WaitForSeconds(spawnInterval);
        }

        isSpawning = false;
    }

    private void SpawnZombie()
    {
        if (zombiePrefab == null || spawnPoints == null || spawnPoints.Length == 0)
            return;

        Transform spawnPoint = spawnPoints[Random.Range(0, spawnPoints.Length)];
        Vector3 spawnPosition = spawnPoint.position + Random.insideUnitSphere * spawnRadius;
        spawnPosition.y = spawnPoint.position.y;

        GameObject zombie = Instantiate(zombiePrefab, spawnPosition, Quaternion.identity);

        ZombieDestroy zombieDestroy = zombie.GetComponent<ZombieDestroy>();
        if (zombieDestroy == null)
        {
            zombieDestroy = zombie.AddComponent<ZombieDestroy>();
        }

        zombieDestroy.OnZombieDestroyed += OnZombieDestroyed;
    }

    private void OnZombieDestroyed()
    {
        zombiesAlive--;
        totalZombiesKilled++;

        if (zombiesAlive <= 0 && !isSpawning)
        {
            OnWaveComplete();
        }
    }

    private void OnWaveComplete()
    {
        isWaveActive = false;
        canStartNextWave = true;
    }
    #endregion

    #region Getters
    public int GetCurrentWave()
    {
        return currentWave;
    }

    public int GetZombiesAlive()
    {
        return zombiesAlive;
    }

    public int GetZombiesInWave()
    {
        return zombiesInCurrentWave;
    }

    public bool IsWaveActive()
    {
        return isWaveActive;
    }

    public bool CanStartNextWave()
    {
        return canStartNextWave;
    }

    public int GetWavesCompleted()
    {
        return isWaveActive ? currentWave - 1 : currentWave;
    }

    public int GetTotalZombiesKilled()
    {
        return totalZombiesKilled;
    }
    #endregion

    private void OnDrawGizmosSelected()
    {
        if (spawnPoints == null || spawnPoints.Length == 0)
        {
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(transform.position, spawnRadius);
            return;
        }

        foreach (Transform point in spawnPoints)
        {
            if (point != null)
            {
                Gizmos.color = Color.cyan;
                Gizmos.DrawWireSphere(point.position, spawnRadius);
            }
        }
    }
}